
#include "../libpatches.h"
#include "idelay.h"
#include "../garbage.h"
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>

static void module_idelay_processor(module m);
void module_idelay_customizer(module m, char * name, char * value);

void module_idelay_initializer(module m) {
	m->customizer = module_idelay_customizer;
}

void module_idelay_customizer(module m, char * name, char * value) {

	//int i;
	//output * o;

	customizer_count_inputs_only(m, name, value);
	if (m->input_count && ! m->inputs) {
		make_outputs(m, m->input_count);
		make_named_inputs(m, m->input_count, 1);
		m->input_names[0] = "in";

		m->processor = module_idelay_processor;

		/* we will dynamically increase the buffer as needed */
		make_buffer(m, 1);

		/* this is the current location in the buffer */
		m->storage = (void *) new_garbage(1, sizeof(int));
	} 
	customizer_buffer_seconds(m, name, value);
	customizer_buffer_size(m, name, value);
}

static void module_idelay_processor(module m) {
	/*
	 * each tap in the delay line is specified in seconds
	 * we must convert this value to samples
	 */
	input * i;
	output * o;
	int count;
	int tap;
	sample tapv;
	sample ntapv;
	double tapr;
	extern int sampling_rate;
	int * start = (int *) m->storage;

	m->buffer[*start] = **(m->named_inputs[0]);

	for (
		count = m->input_count,
		i = m->inputs,
		o = m->outputs;
		count;
		--count, ++i, ++o
	) {
		tapr = abs(***i * sampling_rate);
		tap = tapr;
		tapr -= tap;
		if (tap >= m->buffer_size)
			resize_buffer(m, tap + 1);
		/* interpolate between the current and next sample */
		tapv = m->buffer[(*start + tap) % m->buffer_size];
		ntapv = m->buffer[(*start + tap + 1) % m->buffer_size];
		**o = (1 - tapr) * tapv + tapr * ntapv;
	}

	--(*start);
	if (*start == -1) 
		*start = m->buffer_size - 1;
}
